#ifndef EVENTHANDLER_H
#define EVENTHANDLER_H

/**
 * http://www.gamedev.net/page/resources/_/technical/game-programming/effective-event-handling-in-c-r2459
 */

#include "LibraryCoreExport.h"
#include <map>
#include "Type_Info.h"

namespace CasaEngine
{

	/**
	 * 
	 */
	class LIBRARY_CORE_EXPORT Event
	{
	protected:
		virtual ~Event();
	};

	/**
	 * 
	 */
	class LIBRARY_CORE_EXPORT HandlerFunctionBase
	{
	public:
		virtual ~HandlerFunctionBase();
		void exec(const Event* event);

	private:
		virtual void call(const Event*) = 0;
	};


	/**
	 * 
	 */
	template <class T, class EventT>
	class MemberFunctionHandler : public HandlerFunctionBase
	{
	public:
		typedef void (T::*MemberFunc)(EventT*);
		MemberFunctionHandler(T* instance, MemberFunc memFn) : _instance(instance), _function(memFn) {};

		void call(const Event* event)
		{
			(_instance->*_function)(static_cast<EventT*>(event));
		}

	private:
		T* _instance;
		MemberFunc _function;
	};


	/**
	 * 
	 */
	class LIBRARY_CORE_EXPORT EventHandler
	{
	public:
		~EventHandler();
		void OnFPSChange(const Event*);

		template <class T, class EventT>
		void registerEventFunc(T*, void (T::*memFn)(EventT*));

	private:
		typedef std::map<TypeInfo, HandlerFunctionBase*> Handlers;
		Handlers _handlers;
	};


	/**
	 * 
	 */
	template <class T, class EventT>
	void EventHandler::registerEventFunc(T* obj, void (T::*memFn)(EventT*))
	{
		_handlers[TypeInfo(typeid(EventT))]= new MemberFunctionHandler<T, EventT>(obj, memFn);
	}

} // namespace CasaEngine

#endif
